DEV Community

DEV Community

Paul J. Lucas

Posted on Jun 17, 2023 • Updated on Jul 20, 2023

Dynamically Allocating 2D Arrays Efficiently (and Correctly!) in C

Introduction.

Like many other programming languages, C supports multidimensional arrays (matrices). However, it uses an unconventional syntax for it:

That is, we put each dimension within its own pair of [] . Conceptually, think of 2D matrix as an array of arrays. Under the hood, memory is (always) one-dimensional. To implement the syntactic sugar of two-dimensional arrays, the compiler actually does:

That is in C, all the elements are allocated contiguously such that a2d[i][0] and a2d[i][1] are adjacent in memory for a given row i :

2d matrix layout

(This is known as row-major order .) Given that, the compiler can calculate the address of a2d[i][j] by multiplying i by the length of the row (in this case, 3), then adding j — all scaled by sizeof(T) where T is the element type.

This all works fine for statically allocated 2D matrices where the dimensions are known at compile-time, but what if we don’t know the dimensions at compile-time? We then have to dynamically allocate it. But all C has is malloc() that simply allocates the given number of bytes. How can we allocate the right number of bytes? And how would the compiler know how big each row is to calculate an element’s address so that the [][] syntax still works?

Arrays & Pointers in C

There are a couple of quirky features of C when it comes to arrays and pointers:

The name of an array in an expression “decays” into a pointer to its first element. For example:

That is, the name a1d is a shorthand for &a1d[0] .

The a1d[i] syntax for arrays is just syntactic sugar for *(a1d+i) . That is, take a1d (which is the address of its first element), add sizeof i elements to that address, then dereference that element.

Since addition is commutative, *(a1d+i) can be alternatively written as *(i+a1d) ; that in turn can be written as i[a1d] . Writing it this way has no practical use. It’s just even even quirkier consequence of the [] syntactic sugar.

Equivalently for any pointer p , *p can be alternatively written as p[0] (which is a degenerate case of *(p+0) ). More generally, p[i] is the element at the memory address p plus the offset of i scaled by sizeof(T) . This equivalence allows a one dimensional array to be dynamically allocated and have the [] syntax still work:

This equivalence is a remnant of how pointers are dereferenced in New B (the precursor to C). See The Development of the C Language , Dennis M. Ritchie, April, 1993.

These quirky features of C allow a multidimensional array to be dynamically allocated and have the [][] syntax still work. But how?

Initial Implementation

The trick is instead of allocating a matrix of elements directly, allocate an array of i pointers (one for each row) where each pointer points to an allocated array of j elements for that row:

2D matrix v1

The code to implement this is:

Given that:

That is, m2d[i] yields a pointer to the ith row array of int s that we then index by j . Otherwise unnecessary parentheses can be added as (m2d[i])[j] to make this clearer.

One caveat is that, unlike a statically allocated 2D matrix, a dynamically allocated 2D matrix uses additional memory for the row pointers. Therefore whenever possible for a matrix with dimensions [I][J] , make I ≤ J so you get the most elements per pointer. On the other hand, if you just need a triangular matrix , then it’s possible to write a variant of matrix2d_new() that allocates only i elements for row i . This will only use memory for N ( N +1)/2 elements (if we include the diagonal elements, or N ( N -1)/2 if not), plus N pointers. For a triangular matrix where N ≥ 4, this yields a memory savings.

However, while this implementation is straightforward, the problems with this implementation are that it requires i + 1 calls to malloc() and we’d need to write a corresponding matrix2d_free() function that calls free() an equal number of times.

Better Implementation

If you look at the first illustration, you might realize that there’s no reason the row arrays can’t be coalesced into a single chunk of memory. The row pointers just have to point at the [i][0] element for each row:

2D matrix v2

Declaring elements as char* rather than void* is necessary because we can’t do pointer arithmetic using void* . We need char* specifically because we’re working in terms of bytes.

This is better in that we now only need exactly two calls to malloc() , but we still need to write a corresponding matrix2d_free() function.

Best Implementation

If you look at the second illustration, you might eventually wonder whether the row pointers and elements can be coalesced into one chunk of memory. Yes, they can, but with a pitfall:

2D matrix v3

The pitfall is shown as the shaded area between the row pointers and the elements. This is padding that may be necessary to ensure that the elements are properly aligned .

Specifically, &elements[0][0] must be properly aligned — which means ptrs_size must be rounded up to be a multiple of _Alignof(T) . (A lot of implementations I’ve seen omit this and just so happen to work by luck because _Alignof(T) ≤ sizeof(void*) .)

The code to implement this with proper alignment is:

Notice that the function takes a new ealign parameter that’s _Alignof(T) (or alignof(T) when stdalign.h is included):

This is the best implementation because we now need only one call to malloc() and we don’t need a special matrix2d_free() function: an ordinary free() will do.

The quirky interplay between arrays and pointers in C allows dynamically allocating multidimensional arrays efficiently while still allowing the [][] syntax to work.

Note that we could write matrix3d_new() to dynamically allocate a 3D matrix by using an array of pointers to arrays of pointers to elements; and so on for any number of dimensions; or even a completely generic matrixNd_new() function that takes the number of dimensions as a parameter. (These are left as exercises for the reader.)

If the aforementioned cost of the additional row pointers is too much for your use-case, you can eliminate them, but you have to sacrifice the use of the [][] syntax and write your own accessor function that does what the compiler does under the hood, something like:

But that’s pretty ugly. Like many other things in computer science, it’s a trade-off.

In C++, you can eliminate the row pointers and still use the [][] syntax by use of templates and overloading operator[]() , but that’s a story for another time .

Top comments (2)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

pahujanayan profile image

  • Email [email protected]
  • Location India
  • Education Thapar University
  • Work Student
  • Joined Jun 4, 2023

Hey Paul!, A wonderful read for beginners and intermediate devs. I had some queries about C++ and would like to get in touch with your for the same.

pauljlucas profile image

  • Email [email protected]
  • Location San Francisco Bay Area
  • Education M.S., University of Illinois at Urbana-Champaign
  • Work Retired Principal Software Engineer
  • Joined Jan 21, 2017

I don't offer personal tutoring.

Some comments have been hidden by the post's author - find out more

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

joshalphonse profile image

BMF: Frame extraction acceleration- video similarity search with Pinecone

Josh Alphonse - May 10

carrieke profile image

Weekly Updates - May 10, 2024

Caroline K - May 10

somadevtoo profile image

5 Skills Programmers and Developers Should Learn in 2024

Soma - May 11

orlidev profile image

** Kubernetes: El Mundo Pokemon de la Orquestación de Contenedores **🧒🏻

Orli Dun - May 10

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Learn C practically and Get Certified .

Popular Tutorials

Popular examples, reference materials, learn c interactively, introduction.

  • Getting Started with C
  • Your First C Program
  • C Variables, Constants and Literals
  • C Data Types
  • C Input Output (I/O)
  • C Programming Operators

Flow Control

C if...else Statement

  • C while and do...while Loop
  • C break and continue
  • C switch Statement
  • C goto Statement
  • C Functions
  • C User-defined functions
  • Types of User-defined Functions in C Programming
  • C Recursion
  • C Storage Class

Programming Arrays

C multidimensional arrays.

Pass arrays to a function in C

Programming Pointers

Relationship Between Arrays and Pointers

  • C Pass Addresses and Pointers
  • C Dynamic Memory Allocation
  • C Array and Pointer Examples

Programming Strings

  • C Programming Strings
  • String Manipulations In C Programming Using Library Functions
  • String Examples in C Programming

Structure and Union

  • C structs and Pointers
  • C Structure and Function

Programming Files

  • C File Handling
  • C Files Examples

Additional Topics

  • C Keywords and Identifiers
  • C Precedence And Associativity Of Operators
  • C Bitwise Operators
  • C Preprocessor and Macros
  • C Standard Library Functions

C Tutorials

  • Add Two Matrices Using Multi-dimensional Arrays
  • Multiply Two Matrices Using Multi-dimensional Arrays
  • Find Transpose of a Matrix
  • Multiply two Matrices by Passing Matrix to a Function
  • Store Information of Students Using Structure

In C programming, you can create an array of arrays. These arrays are known as multidimensional arrays. For example,

Here, x is a two-dimensional (2d) array. The array can hold 12 elements. You can think the array as a table with 3 rows and each row has 4 columns.

Two dimensional array in C programming

Similarly, you can declare a three-dimensional (3d) array. For example,

Here, the array y can hold 24 elements.

  • Initializing a multidimensional array

Here is how you can initialize two-dimensional and three-dimensional arrays:

Initialization of a 2d array

Initialization of a 3d array.

You can initialize a three-dimensional array in a similar way to a two-dimensional array. Here's an example,

Example 1: Two-dimensional array to store and print values

Example 2: sum of two matrices, example 3: three-dimensional array, table of contents.

  • Multidimensional array (Introduction)
  • Example: 2d array to store and print values
  • Example: Sum of two matrices
  • Example: Three Dimensional Array

Video: C Multidimensional Arrays

Sorry about that.

Related Tutorials

cppreference.com

Assignment operators.

Assignment and compound assignment operators are binary operators that modify the variable to their left using the value to their right.

[ edit ] Simple assignment

The simple assignment operator expressions have the form

Assignment performs implicit conversion from the value of rhs to the type of lhs and then replaces the value in the object designated by lhs with the converted value of rhs .

Assignment also returns the same value as what was stored in lhs (so that expressions such as a = b = c are possible). The value category of the assignment operator is non-lvalue (so that expressions such as ( a = b ) = c are invalid).

rhs and lhs must satisfy one of the following:

  • both lhs and rhs have compatible struct or union type, or..
  • rhs must be implicitly convertible to lhs , which implies
  • both lhs and rhs have arithmetic types , in which case lhs may be volatile -qualified or atomic (since C11)
  • both lhs and rhs have pointer to compatible (ignoring qualifiers) types, or one of the pointers is a pointer to void, and the conversion would not add qualifiers to the pointed-to type. lhs may be volatile or restrict (since C99) -qualified or atomic (since C11) .
  • lhs is a (possibly qualified or atomic (since C11) ) pointer and rhs is a null pointer constant such as NULL or a nullptr_t value (since C23)

[ edit ] Notes

If rhs and lhs overlap in memory (e.g. they are members of the same union), the behavior is undefined unless the overlap is exact and the types are compatible .

Although arrays are not assignable, an array wrapped in a struct is assignable to another object of the same (or compatible) struct type.

The side effect of updating lhs is sequenced after the value computations, but not the side effects of lhs and rhs themselves and the evaluations of the operands are, as usual, unsequenced relative to each other (so the expressions such as i = ++ i ; are undefined)

Assignment strips extra range and precision from floating-point expressions (see FLT_EVAL_METHOD ).

In C++, assignment operators are lvalue expressions, not so in C.

[ edit ] Compound assignment

The compound assignment operator expressions have the form

The expression lhs @= rhs is exactly the same as lhs = lhs @ ( rhs ) , except that lhs is evaluated only once.

[ edit ] References

  • C17 standard (ISO/IEC 9899:2018):
  • 6.5.16 Assignment operators (p: 72-73)
  • C11 standard (ISO/IEC 9899:2011):
  • 6.5.16 Assignment operators (p: 101-104)
  • C99 standard (ISO/IEC 9899:1999):
  • 6.5.16 Assignment operators (p: 91-93)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 3.3.16 Assignment operators

[ edit ] See Also

Operator precedence

[ edit ] See also

  • Recent changes
  • Offline version
  • What links here
  • Related changes
  • Upload file
  • Special pages
  • Printable version
  • Permanent link
  • Page information
  • In other languages
  • This page was last modified on 19 August 2022, at 08:36.
  • This page has been accessed 54,567 times.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

C Programming Tutorial

  • Pointers and 2-D arrays

Last updated on July 27, 2020

In the last chapter, we have created a pointer which points to the 0th element of the array whose base type was ( int * ) or pointer to int . We can also create a pointer that can point to the whole array instead of only one element of the array. This is known as a pointer to an array. Here is how you can declare a pointer to an array.

Here p is a pointer that can point to an array of 10 integers. In this case, the type or base type of p is a pointer to an array of 10 integers.

Note that parentheses around p are necessary, so you can't do this:

here p is an array of 10 integer pointers. An array of pointers will be discussed in upcoming chapters.

A pointer that points to the 0th element of an array and a pointer that points to the whole array are totally different. The following program demonstrates this concept.

Expected Output:

How it works:

Here p is a pointer which points to the 0th element of the array my_arr , while parr is a pointer which points to the whole array my_arr . The base type of p is of type ( int * ) or pointer to int and base type of parr is pointer to an array of 5 integers. Since the pointer arithmetic is performed relative to the base type of the pointer, that's why parr is incremented by 20 bytes i.e ( 5 x 4 = 20 bytes ). On the other hand, p is incremented by 4 bytes only.

The important point you need to remember about pointer to an array is this:

Whenever a pointer to an array is dereferenced we get the address (or base address) of the array to which it points.

So, on dereferencing parr , you will get *parr . The important thing to notice is although parr and *parr points to the same address, but parr's base type is a pointer to an array of 5 integers, while *parr base type is a pointer to int. This is an important concept and will be used to access the elements of a 2-D array.

Pointers and 2-D Array #

While discussing 2-D array in the earlier chapters, we told you to visualize a 2-D array as a matrix. For example:

The above 2-D array can be visualized as following:

assignment operator 2d array c

While discussing array we are using terms like rows and column. Well, this concept is only theoretical, because computer memory is linear and there are no rows and cols. So how actually 2-D arrays are stored in memory ? In C, arrays are stored row-major order. This simply means that first row 0 is stored, then next to it row 1 is stored, next to it row 2 is stored and so on.

The following figure shows how a 2-D array is stored in the memory.

assignment operator 2d array c

Here is the most important concept you need to remember about a multi-dimensional array.

A 2-D array is actually a 1-D array in which each element is itself a 1-D array. So arr is an array of 3 elements where each element is a 1-D array of 4 integers.

In the previous chapter, we have already discussed that the name of a 1-D array is a constant pointer to the 0th element. In the case, of a 2-D array, 0th element is a 1-D array. Hence in the above example, the type or base type of arr is a pointer to an array of 4 integers. Since pointer arithmetic is performed relative to the base size of the pointer. In the case of arr , if arr points to address 2000 then arr + 1 points to address 2016 (i.e 2000 + 4*4 ).

We know that the name of the array is a constant pointer that points to the 0th element of the array. In the case of a 2-D array, 0th element is a 1-D array. So the name of the array in case of a 2-D array represents a pointer to the 0th 1-D array. Therefore in this case arr is a pointer to an array of 4 elements. If the address of the 0th 1-D is 2000 , then according to pointer arithmetic ( arr + 1 ) will represent the address 2016 , similarly ( arr + 2 ) will represent the address 2032 .

From the above discussion, we can conclude that:

arr points to 0th 1-D array. (arr + 1) points to 1st 1-D array. (arr + 2) points to 2nd 1-D array.

assignment operator 2d array c

In general, we can write:

(arr + i) points to ith 1-D array.

As we discussed earlier in this chapter that dereferencing a pointer to an array gives the base address of the array. So dereferencing arr we will get *arr , base type of *arr is (int*) . Similarly, on dereferencing arr+1 we will get *(arr+1) . In general, we can say that:

*(arr+i) points to the base address of the ith 1-D array.

Again it is important to note that type (arr + i) and *(arr+i) points to same address but their base types are completely different. The base type of (arr + i) is a pointer to an array of 4 integers, while the base type of *(arr + i) is a pointer to int or ( int* ).

So how you can use arr to access individual elements of a 2-D array?

Since *(arr + i) points to the base address of every ith 1-D array and it is of base type pointer to int , by using pointer arithmetic we should we able to access elements of ith 1-D array.

Let's see how we can do this:

*(arr + i) points to the address of the 0th element of the 1-D array. So, *(arr + i) + 1 points to the address of the 1st element of the 1-D array *(arr + i) + 2 points to the address of the 2nd element of the 1-D array

Hence we can conclude that:

*(arr + i) + j points to the base address of jth element of ith 1-D array.

On dereferencing *(arr + i) + j we will get the value of jth element of ith 1-D array.

By using this expression we can find the value of jth element of ith 1-D array.

Furthermore, the pointer notation *(*(arr + i) + j) is equivalent to the subscript notation.

The following program demonstrates how to access values and address of elements of a 2-D array using pointer notation.

Assigning 2-D Array to a Pointer Variable #

You can assign the name of the array to a pointer variable, but unlike 1-D array you will need pointer to an array instead of pointer to int or ( int * ) . Here is an example:

Always remember a 2-D array is actually a 1-D array where each element is a 1-D array. So arr as an array of 2 elements where each element is a 1-D arr of 3 integers. Hence to store the base address of arr , you will need a pointer to an array of 3 integers.

Similarly, If a 2-D array has 3 rows and 4 cols i.e int arr[3][4] , then you will need a pointer to an array of 4 integers.

Here p is a pointer to an array of 3 integers. So according to pointer arithmetic p+i points to the ith 1-D array, in other words, p+0 points to the 0th 1-D array, p+1 points to the 1st 1-D array and so on. The base type of ( p+i ) is a pointer to an array of 3 integers. If we dereference ( p+i ) then we will get the base address of ith 1-D array but now the base type of *(p + i) is a pointer to int or ( int * ). Again to access the address of jth element ith 1-D array, we just have to add j to *(p + i) . So *(p + i) + j points to the address of jth element of ith 1-D array. Therefore the expression *(*(p + i) + j) gives the value of jth element of ith 1-D array.

The following program demonstrates how to access elements of a 2-D array using a pointer to an array.

Load Comments

  • Intro to C Programming
  • Installing Code Blocks
  • Creating and Running The First C Program
  • Basic Elements of a C Program
  • Keywords and Identifiers
  • Data Types in C
  • Constants in C
  • Variables in C
  • Input and Output in C
  • Formatted Input and Output in C
  • Arithmetic Operators in C
  • Operator Precedence and Associativity in C
  • Assignment Operator in C
  • Increment and Decrement Operators in C
  • Relational Operators in C
  • Logical Operators in C
  • Conditional Operator, Comma operator and sizeof() operator in C
  • Implicit Type Conversion in C
  • Explicit Type Conversion in C
  • if-else statements in C
  • The while loop in C
  • The do while loop in C
  • The for loop in C
  • The Infinite Loop in C
  • The break and continue statement in C
  • The Switch statement in C
  • Function basics in C
  • The return statement in C
  • Actual and Formal arguments in C
  • Local, Global and Static variables in C
  • Recursive Function in C
  • One dimensional Array in C
  • One Dimensional Array and Function in C
  • Two Dimensional Array in C
  • Pointer Basics in C
  • Pointer Arithmetic in C
  • Pointers and 1-D arrays
  • Call by Value and Call by Reference in C
  • Returning more than one value from function in C
  • Returning a Pointer from a Function in C
  • Passing 1-D Array to a Function in C
  • Passing 2-D Array to a Function in C
  • Array of Pointers in C
  • Void Pointers in C
  • The malloc() Function in C
  • The calloc() Function in C
  • The realloc() Function in C
  • String Basics in C
  • The strlen() Function in C
  • The strcmp() Function in C
  • The strcpy() Function in C
  • The strcat() Function in C
  • Character Array and Character Pointer in C
  • Array of Strings in C
  • Array of Pointers to Strings in C
  • The sprintf() Function in C
  • The sscanf() Function in C
  • Structure Basics in C
  • Array of Structures in C
  • Array as Member of Structure in C
  • Nested Structures in C
  • Pointer to a Structure in C
  • Pointers as Structure Member in C
  • Structures and Functions in C
  • Union Basics in C
  • typedef statement in C
  • Basics of File Handling in C
  • fputc() Function in C
  • fgetc() Function in C
  • fputs() Function in C
  • fgets() Function in C
  • fprintf() Function in C
  • fscanf() Function in C
  • fwrite() Function in C
  • fread() Function in C

Recent Posts

  • Machine Learning Experts You Should Be Following Online
  • 4 Ways to Prepare for the AP Computer Science A Exam
  • Finance Assignment Online Help for the Busy and Tired Students: Get Help from Experts
  • Top 9 Machine Learning Algorithms for Data Scientists
  • Data Science Learning Path or Steps to become a data scientist Final
  • Enable Edit Button in Shutter In Linux Mint 19 and Ubuntu 18.04
  • Python 3 time module
  • Pygments Tutorial
  • How to use Virtualenv?
  • Installing MySQL (Windows, Linux and Mac)
  • What is if __name__ == '__main__' in Python ?
  • Installing GoAccess (A Real-time web log analyzer)
  • Installing Isso

CProgramming Tutorial

  • C Programming Tutorial
  • C - Overview
  • C - Features
  • C - History
  • C - Environment Setup
  • C - Program Structure
  • C - Hello World
  • C - Compilation Process
  • C - Comments
  • C - Keywords
  • C - Identifiers
  • C - User Input
  • C - Basic Syntax
  • C - Data Types
  • C - Variables
  • C - Integer Promotions
  • C - Type Conversion
  • C - Booleans
  • C - Constants
  • C - Literals
  • C - Escape sequences
  • C - Format Specifiers
  • C - Storage Classes
  • C - Operators
  • C - Arithmetic Operators
  • C - Relational Operators
  • C - Logical Operators
  • C - Bitwise Operators
  • C - Assignment Operators
  • C - Unary Operators
  • C - Increment and Decrement Operators
  • C - Ternary Operator
  • C - sizeof Operator
  • C - Operator Precedence
  • C - Misc Operators
  • C - Decision Making
  • C - if statement
  • C - if...else statement
  • C - nested if statements
  • C - switch statement
  • C - nested switch statements
  • C - While loop
  • C - For loop
  • C - Do...while loop
  • C - Nested loop
  • C - Infinite loop
  • C - Break Statement
  • C - Continue Statement
  • C - goto Statement
  • C - Functions
  • C - Main Functions
  • C - Function call by Value
  • C - Function call by reference
  • C - Nested Functions
  • C - Variadic Functions
  • C - User-Defined Functions
  • C - Callback Function
  • C - Return Statement
  • C - Recursion
  • C - Scope Rules
  • C - Static Variables
  • C - Global Variables
  • C - Properties of Array
  • C - Multi-Dimensional Arrays
  • C - Passing Arrays to Function
  • C - Return Array from Function
  • C - Variable Length Arrays
  • C - Pointers
  • C - Pointers and Arrays
  • C - Applications of Pointers
  • C - Pointer Arithmetics
  • C - Array of Pointers
  • C - Passing Pointers to Functions
  • C - Strings
  • C - Array of Strings
  • C - Structures
  • C - Structures and Functions
  • C - Arrays of Structures
  • C - Pointers to Structures
  • C - Self-Referential Structures
  • C - Nested Structures
  • C - Bit Fields
  • C - Typedef
  • C - Input & Output
  • C - File I/O
  • C - Preprocessors
  • C - Header Files
  • C - Type Casting
  • C - Error Handling
  • C - Variable Arguments
  • C - Memory Management
  • C - Command Line Arguments
  • C Programming Resources
  • C - Questions & Answers
  • C - Quick Guide
  • C - Useful Resources
  • C - Discussion
  • Selected Reading
  • UPSC IAS Exams Notes
  • Developer's Best Practices
  • Questions and Answers
  • Effective Resume Writing
  • HR Interview Questions
  • Computer Glossary

Assignment Operators in C

In C language, the assignment operator stores a certain value in an already declared variable. A variable in C can be assigned the value in the form of a literal, another variable, or an expression.

The value to be assigned forms the right-hand operand, whereas the variable to be assigned should be the operand to the left of the " = " symbol, which is defined as a simple assignment operator in C.

In addition, C has several augmented assignment operators.

The following table lists the assignment operators supported by the C language −

Simple Assignment Operator (=)

The = operator is one of the most frequently used operators in C. As per the ANSI C standard, all the variables must be declared in the beginning. Variable declaration after the first processing statement is not allowed.

You can declare a variable to be assigned a value later in the code, or you can initialize it at the time of declaration.

You can use a literal, another variable, or an expression in the assignment statement.

Once a variable of a certain type is declared, it cannot be assigned a value of any other type. In such a case the C compiler reports a type mismatch error.

In C, the expressions that refer to a memory location are called "lvalue" expressions. A lvalue may appear as either the left-hand or right-hand side of an assignment.

On the other hand, the term rvalue refers to a data value that is stored at some address in memory. A rvalue is an expression that cannot have a value assigned to it which means an rvalue may appear on the right-hand side but not on the left-hand side of an assignment.

Variables are lvalues and so they may appear on the left-hand side of an assignment. Numeric literals are rvalues and so they may not be assigned and cannot appear on the left-hand side. Take a look at the following valid and invalid statements −

Augmented Assignment Operators

In addition to the = operator, C allows you to combine arithmetic and bitwise operators with the = symbol to form augmented or compound assignment operator. The augmented operators offer a convenient shortcut for combining arithmetic or bitwise operation with assignment.

For example, the expression "a += b" has the same effect of performing "a + b" first and then assigning the result back to the variable "a".

Run the code and check its output −

Similarly, the expression "a <<= b" has the same effect of performing "a << b" first and then assigning the result back to the variable "a".

Here is a C program that demonstrates the use of assignment operators in C −

When you compile and execute the above program, it will produce the following result −

To Continue Learning Please Login

Learn C++

21.12 — Overloading the assignment operator

The copy assignment operator (operator=) is used to copy values from one object to another already existing object .

Related content

As of C++11, C++ also supports “Move assignment”. We discuss move assignment in lesson 22.3 -- Move constructors and move assignment .

Copy assignment vs Copy constructor

The purpose of the copy constructor and the copy assignment operator are almost equivalent -- both copy one object to another. However, the copy constructor initializes new objects, whereas the assignment operator replaces the contents of existing objects.

The difference between the copy constructor and the copy assignment operator causes a lot of confusion for new programmers, but it’s really not all that difficult. Summarizing:

  • If a new object has to be created before the copying can occur, the copy constructor is used (note: this includes passing or returning objects by value).
  • If a new object does not have to be created before the copying can occur, the assignment operator is used.

Overloading the assignment operator

Overloading the copy assignment operator (operator=) is fairly straightforward, with one specific caveat that we’ll get to. The copy assignment operator must be overloaded as a member function.

This prints:

This should all be pretty straightforward by now. Our overloaded operator= returns *this, so that we can chain multiple assignments together:

Issues due to self-assignment

Here’s where things start to get a little more interesting. C++ allows self-assignment:

This will call f1.operator=(f1), and under the simplistic implementation above, all of the members will be assigned to themselves. In this particular example, the self-assignment causes each member to be assigned to itself, which has no overall impact, other than wasting time. In most cases, a self-assignment doesn’t need to do anything at all!

However, in cases where an assignment operator needs to dynamically assign memory, self-assignment can actually be dangerous:

First, run the program as it is. You’ll see that the program prints “Alex” as it should.

Now run the following program:

You’ll probably get garbage output. What happened?

Consider what happens in the overloaded operator= when the implicit object AND the passed in parameter (str) are both variable alex. In this case, m_data is the same as str.m_data. The first thing that happens is that the function checks to see if the implicit object already has a string. If so, it needs to delete it, so we don’t end up with a memory leak. In this case, m_data is allocated, so the function deletes m_data. But because str is the same as *this, the string that we wanted to copy has been deleted and m_data (and str.m_data) are dangling.

Later on, we allocate new memory to m_data (and str.m_data). So when we subsequently copy the data from str.m_data into m_data, we’re copying garbage, because str.m_data was never initialized.

Detecting and handling self-assignment

Fortunately, we can detect when self-assignment occurs. Here’s an updated implementation of our overloaded operator= for the MyString class:

By checking if the address of our implicit object is the same as the address of the object being passed in as a parameter, we can have our assignment operator just return immediately without doing any other work.

Because this is just a pointer comparison, it should be fast, and does not require operator== to be overloaded.

When not to handle self-assignment

Typically the self-assignment check is skipped for copy constructors. Because the object being copy constructed is newly created, the only case where the newly created object can be equal to the object being copied is when you try to initialize a newly defined object with itself:

In such cases, your compiler should warn you that c is an uninitialized variable.

Second, the self-assignment check may be omitted in classes that can naturally handle self-assignment. Consider this Fraction class assignment operator that has a self-assignment guard:

If the self-assignment guard did not exist, this function would still operate correctly during a self-assignment (because all of the operations done by the function can handle self-assignment properly).

Because self-assignment is a rare event, some prominent C++ gurus recommend omitting the self-assignment guard even in classes that would benefit from it. We do not recommend this, as we believe it’s a better practice to code defensively and then selectively optimize later.

The copy and swap idiom

A better way to handle self-assignment issues is via what’s called the copy and swap idiom. There’s a great writeup of how this idiom works on Stack Overflow .

The implicit copy assignment operator

Unlike other operators, the compiler will provide an implicit public copy assignment operator for your class if you do not provide a user-defined one. This assignment operator does memberwise assignment (which is essentially the same as the memberwise initialization that default copy constructors do).

Just like other constructors and operators, you can prevent assignments from being made by making your copy assignment operator private or using the delete keyword:

Note that if your class has const members, the compiler will instead define the implicit operator= as deleted. This is because const members can’t be assigned, so the compiler will assume your class should not be assignable.

If you want a class with const members to be assignable (for all members that aren’t const), you will need to explicitly overload operator= and manually assign each non-const member.

guest

Codeforwin

Assignment and shorthand assignment operator in C

Quick links.

  • Shorthand assignment

Assignment operator is used to assign value to a variable (memory location). There is a single assignment operator = in C. It evaluates expression on right side of = symbol and assigns evaluated value to left side the variable.

For example consider the below assignment table.

The RHS of assignment operator must be a constant, expression or variable. Whereas LHS must be a variable (valid memory location).

Shorthand assignment operator

C supports a short variant of assignment operator called compound assignment or shorthand assignment. Shorthand assignment operator combines one of the arithmetic or bitwise operators with assignment operator.

For example, consider following C statements.

The above expression a = a + 2 is equivalent to a += 2 .

Similarly, there are many shorthand assignment operators. Below is a list of shorthand assignment operators in C.

  • Windows Programming
  • UNIX/Linux Programming
  • General C++ Programming
  • copy assignment operator - arrays

  copy assignment operator - arrays

assignment operator 2d array c

  • Python Basics
  • Interview Questions
  • Python Quiz
  • Popular Packages
  • Python Projects
  • Practice Python
  • AI With Python
  • Learn Python3
  • Python Automation
  • Python Web Dev
  • DSA with Python
  • Python OOPs
  • Dictionaries

Python Operators

Precedence and associativity of operators in python.

  • Python Arithmetic Operators
  • Difference between / vs. // operator in Python
  • Python - Star or Asterisk operator ( * )
  • What does the Double Star operator mean in Python?
  • Division Operators in Python
  • Modulo operator (%) in Python
  • Python Logical Operators
  • Python OR Operator
  • Difference between 'and' and '&' in Python
  • not Operator in Python | Boolean Logic

Ternary Operator in Python

  • Python Bitwise Operators

Python Assignment Operators

Assignment operators in python.

  • Walrus Operator in Python 3.8
  • Increment += and Decrement -= Assignment Operators in Python
  • Merging and Updating Dictionary Operators in Python 3.9
  • New '=' Operator in Python3.8 f-string

Python Relational Operators

  • Comparison Operators in Python
  • Python NOT EQUAL operator
  • Difference between == and is operator in Python
  • Chaining comparison operators in Python
  • Python Membership and Identity Operators
  • Difference between != and is not operator in Python

In Python programming, Operators in general are used to perform operations on values and variables. These are standard symbols used for logical and arithmetic operations. In this article, we will look into different types of Python operators. 

  • OPERATORS: These are the special symbols. Eg- + , * , /, etc.
  • OPERAND: It is the value on which the operator is applied.

Types of Operators in Python

  • Arithmetic Operators
  • Comparison Operators
  • Logical Operators
  • Bitwise Operators
  • Assignment Operators
  • Identity Operators and Membership Operators

Python Operators

Arithmetic Operators in Python

Python Arithmetic operators are used to perform basic mathematical operations like addition, subtraction, multiplication , and division .

In Python 3.x the result of division is a floating-point while in Python 2.x division of 2 integers was an integer. To obtain an integer result in Python 3.x floored (// integer) is used.

Example of Arithmetic Operators in Python

Division operators.

In Python programming language Division Operators allow you to divide two numbers and return a quotient, i.e., the first number or number at the left is divided by the second number or number at the right and returns the quotient. 

There are two types of division operators: 

Float division

  • Floor division

The quotient returned by this operator is always a float number, no matter if two numbers are integers. For example:

Example: The code performs division operations and prints the results. It demonstrates that both integer and floating-point divisions return accurate results. For example, ’10/2′ results in ‘5.0’ , and ‘-10/2’ results in ‘-5.0’ .

Integer division( Floor division)

The quotient returned by this operator is dependent on the argument being passed. If any of the numbers is float, it returns output in float. It is also known as Floor division because, if any number is negative, then the output will be floored. For example:

Example: The code demonstrates integer (floor) division operations using the // in Python operators . It provides results as follows: ’10//3′ equals ‘3’ , ‘-5//2’ equals ‘-3’ , ‘ 5.0//2′ equals ‘2.0’ , and ‘-5.0//2’ equals ‘-3.0’ . Integer division returns the largest integer less than or equal to the division result.

Precedence of Arithmetic Operators in Python

The precedence of Arithmetic Operators in Python is as follows:

  • P – Parentheses
  • E – Exponentiation
  • M – Multiplication (Multiplication and division have the same precedence)
  • D – Division
  • A – Addition (Addition and subtraction have the same precedence)
  • S – Subtraction

The modulus of Python operators helps us extract the last digit/s of a number. For example:

  • x % 10 -> yields the last digit
  • x % 100 -> yield last two digits

Arithmetic Operators With Addition, Subtraction, Multiplication, Modulo and Power

Here is an example showing how different Arithmetic Operators in Python work:

Example: The code performs basic arithmetic operations with the values of ‘a’ and ‘b’ . It adds (‘+’) , subtracts (‘-‘) , multiplies (‘*’) , computes the remainder (‘%’) , and raises a to the power of ‘b (**)’ . The results of these operations are printed.

Note: Refer to Differences between / and // for some interesting facts about these two Python operators.

Comparison of Python Operators

In Python Comparison of Relational operators compares the values. It either returns True or False according to the condition.

= is an assignment operator and == comparison operator.

Precedence of Comparison Operators in Python

In Python, the comparison operators have lower precedence than the arithmetic operators. All the operators within comparison operators have the same precedence order.

Example of Comparison Operators in Python

Let’s see an example of Comparison Operators in Python.

Example: The code compares the values of ‘a’ and ‘b’ using various comparison Python operators and prints the results. It checks if ‘a’ is greater than, less than, equal to, not equal to, greater than, or equal to, and less than or equal to ‘b’ .

Logical Operators in Python

Python Logical operators perform Logical AND , Logical OR , and Logical NOT operations. It is used to combine conditional statements.

Precedence of Logical Operators in Python

The precedence of Logical Operators in Python is as follows:

  • Logical not
  • logical and

Example of Logical Operators in Python

The following code shows how to implement Logical Operators in Python:

Example: The code performs logical operations with Boolean values. It checks if both ‘a’ and ‘b’ are true ( ‘and’ ), if at least one of them is true ( ‘or’ ), and negates the value of ‘a’ using ‘not’ . The results are printed accordingly.

Bitwise Operators in Python

Python Bitwise operators act on bits and perform bit-by-bit operations. These are used to operate on binary numbers.

Precedence of Bitwise Operators in Python

The precedence of Bitwise Operators in Python is as follows:

  • Bitwise NOT
  • Bitwise Shift
  • Bitwise AND
  • Bitwise XOR

Here is an example showing how Bitwise Operators in Python work:

Example: The code demonstrates various bitwise operations with the values of ‘a’ and ‘b’ . It performs bitwise AND (&) , OR (|) , NOT (~) , XOR (^) , right shift (>>) , and left shift (<<) operations and prints the results. These operations manipulate the binary representations of the numbers.

Python Assignment operators are used to assign values to the variables.

Let’s see an example of Assignment Operators in Python.

Example: The code starts with ‘a’ and ‘b’ both having the value 10. It then performs a series of operations: addition, subtraction, multiplication, and a left shift operation on ‘b’ . The results of each operation are printed, showing the impact of these operations on the value of ‘b’ .

Identity Operators in Python

In Python, is and is not are the identity operators both are used to check if two values are located on the same part of the memory. Two variables that are equal do not imply that they are identical. 

Example Identity Operators in Python

Let’s see an example of Identity Operators in Python.

Example: The code uses identity operators to compare variables in Python. It checks if ‘a’ is not the same object as ‘b’ (which is true because they have different values) and if ‘a’ is the same object as ‘c’ (which is true because ‘c’ was assigned the value of ‘a’ ).

Membership Operators in Python

In Python, in and not in are the membership operators that are used to test whether a value or variable is in a sequence.

Examples of Membership Operators in Python

The following code shows how to implement Membership Operators in Python:

Example: The code checks for the presence of values ‘x’ and ‘y’ in the list. It prints whether or not each value is present in the list. ‘x’ is not in the list, and ‘y’ is present, as indicated by the printed messages. The code uses the ‘in’ and ‘not in’ Python operators to perform these checks.

in Python, Ternary operators also known as conditional expressions are operators that evaluate something based on a condition being true or false. It was added to Python in version 2.5. 

It simply allows testing a condition in a single line replacing the multiline if-else making the code compact.

Syntax :   [on_true] if [expression] else [on_false] 

Examples of Ternary Operator in Python

The code assigns values to variables ‘a’ and ‘b’ (10 and 20, respectively). It then uses a conditional assignment to determine the smaller of the two values and assigns it to the variable ‘min’ . Finally, it prints the value of ‘min’ , which is 10 in this case.

In Python, Operator precedence and associativity determine the priorities of the operator.

Operator Precedence in Python

This is used in an expression with more than one operator with different precedence to determine which operation to perform first.

Let’s see an example of how Operator Precedence in Python works:

Example: The code first calculates and prints the value of the expression 10 + 20 * 30 , which is 610. Then, it checks a condition based on the values of the ‘name’ and ‘age’ variables. Since the name is “ Alex” and the condition is satisfied using the or operator, it prints “Hello! Welcome.”

Operator Associativity in Python

If an expression contains two or more operators with the same precedence then Operator Associativity is used to determine. It can either be Left to Right or from Right to Left.

The following code shows how Operator Associativity in Python works:

Example: The code showcases various mathematical operations. It calculates and prints the results of division and multiplication, addition and subtraction, subtraction within parentheses, and exponentiation. The code illustrates different mathematical calculations and their outcomes.

To try your knowledge of Python Operators, you can take out the quiz on Operators in Python . 

Python Operator Exercise Questions

Below are two Exercise Questions on Python Operators. We have covered arithmetic operators and comparison operators in these exercise questions. For more exercises on Python Operators visit the page mentioned below.

Q1. Code to implement basic arithmetic operations on integers

Q2. Code to implement Comparison operations on integers

Explore more Exercises: Practice Exercise on Operators in Python

Please Login to comment...

Similar reads.

  • python-basics
  • Python-Operators

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

IMAGES

  1. Two Dimensional Array in C++

    assignment operator 2d array c

  2. Two Dimensional Array in C++

    assignment operator 2d array c

  3. Assignment Operators in C

    assignment operator 2d array c

  4. Tutorial 10

    assignment operator 2d array c

  5. Assignment Operators in C » PREP INSTA

    assignment operator 2d array c

  6. 2D arrays in C

    assignment operator 2d array c

VIDEO

  1. Sigma

  2. Part 7

  3. Augmented assignment operators in C

  4. 06 Java Operator

  5. Operators in C++

  6. C++ Multiple and Combined Assignment Explained: Tips and Examples [5]

COMMENTS

  1. c

    Jun 24, 2018 at 16:00. Given int i = 1; int j = 2; i = j;, the assignment actually copies the value from the address identified by j into the address identified by i. There's not much difference when the assignment is names[1][2] = names[2][1]; instead. Yes, the l-value (on the left-hand side or LHS of the assignment) is more complex, and the r ...

  2. How to declare a 2D array dynamically in C++ using new operator

    Syntax of a 2D array: data_type array_name [x] [y]; data_type: Type of data to be stored. Valid C/C++ data type. Below is the diagrammatic representation of 2D arrays: For more details on multidimensional and 2D arrays, please refer to Multidimensional arrays in C++ article. Problem: Given a 2D array, the task is to dynamically allocate memory ...

  3. Two Dimensional Array in C

    Two-dimensional Array. The syntax declaration of 2-D array is not much different from 1-D array. In 2-D array, to declare and access elements of a 2-D array we use 2 subscripts instead of 1. Syntax: datatype array_name[ROW][COL]; The total number of elements in a 2-D array is ROW*COL.

  4. Multidimensional Arrays in C

    A multi-dimensional array can be termed as an array of arrays that stores homogeneous data in tabular form. Data in multidimensional arrays is generally stored in row-major order in the memory. The general form of declaring N-dimensional arrays is shown below. Syntax: data_type: Type of data to be stored in the array.

  5. How to Initialize a 2D Array in C?

    It has two dimensions so it can store the data in two directions i.e. rows and columns. In this article, we will learn how to initialize a 2D array in C. Initialize Two Dimensional Array in C. We can simply initialize a 2D array at the time of declaration by providing the values in curly braces {} using the below syntax:

  6. Dynamically Allocating 2D Arrays Efficiently (and Correctly!) in C

    The quirky interplay between arrays and pointers in C allows dynamically allocating multidimensional arrays efficiently while still ... In C++, you can eliminate the row pointers and still use the [][] syntax by use of templates and overloading operator[](), but that's a story for another time. Top comments (2) Subscribe. Personal Trusted User.

  7. C Multidimensional Arrays (2d and 3d Array)

    C Multidimensional Arrays. In C programming, you can create an array of arrays. These arrays are known as multidimensional arrays. For example, float x[3][4]; Here, x is a two-dimensional (2d) array. The array can hold 12 elements. You can think the array as a table with 3 rows and each row has 4 columns.

  8. Assignment operators

    Assignment performs implicit conversion from the value of rhs to the type of lhs and then replaces the value in the object designated by lhs with the converted value of rhs . Assignment also returns the same value as what was stored in lhs (so that expressions such as a = b = c are possible). The value category of the assignment operator is non ...

  9. Pointers and 2-D arrays

    4. int arr[2][3] = { {33, 44, 55}, {11, 99, 66} }; Always remember a 2-D array is actually a 1-D array where each element is a 1-D array. So arr as an array of 2 elements where each element is a 1-D arr of 3 integers. Hence to store the base address of arr, you will need a pointer to an array of 3 integers.

  10. Assignment Operators in C

    Assigns values from right side operands to left side operand. C = A + B will assign the value of A + B to C. +=. Add AND assignment operator. It adds the right operand to the left operand and assign the result to the left operand. C += A is equivalent to C = C + A. -=. Subtract AND assignment operator.

  11. C Arrays

    Array in C is one of the most used data structures in C programming. It is a simple and fast way of storing multiple values under a single name. In this article, we will study the different aspects of array in C language such as array declaration, definition, initialization, types of arrays, array syntax, advantages and disadvantages, and many ...

  12. 21.12

    21.12 — Overloading the assignment operator. The copy assignment operator (operator=) is used to copy values from one object to another already existing object. As of C++11, C++ also supports "Move assignment". We discuss move assignment in lesson 22.3 -- Move constructors and move assignment .

  13. Assignment and shorthand assignment operator in C

    C supports a short variant of assignment operator called compound assignment or shorthand assignment. Shorthand assignment operator combines one of the arithmetic or bitwise operators with assignment operator. For example, consider following C statements. int a = 5; a = a + 2; The above expression a = a + 2 is equivalent to a += 2. Similarly ...

  14. copy assignment operator

    What you have above does not work on C arrays, they can't use the assignment operator. If they could, it would, presumably, work just like integers: int a; int b; a = b; //b still exists, of course, and still has its value! it would be unusual to make a custom operator for any type (arrays or not) that self-destructed the right hand side ...

  15. One Dimensional Arrays in C

    Then, we can also assign the new value to the element using assignment operator. array_name [index] = new_value; // updating element. Note: Make sure the index lies within the array or else it might lead to segmentation fault. To access all the elements of the array at once, we can use the loops as shown below. Example of One Dimensional Array in C

  16. c++ overload operator() for assigning value in a dynamic 2D array

    5. Your first overload must be in form: int operator() (int row, int col) const. Not. const int operator() (int row, int col) And it is not the read operation, it is used when an object of your type is created as const, this overload will be used, if not const, other overload will be used, both for reading and writing.

  17. C++ Multidimensional Array

    Syntax: dataType arrayName[d][r]; dataType: Type of data to be stored in each element. arrayName: Name of the array d: Number of 2D arrays or Depth of array. r: Number of rows in each 2D array. c: Number of columns in each 2D array. Example: int array[3][5][2]; Initialization of Three-Dimensional Array in C++. To initialize the 3D array in C++, we follow the same methods we have used to ...

  18. c++

    I am trying to write a simple chess program using object oriented programming. So far I have a board initialized to a 2d array of pointers. I can place pieces on the board, print the board and move the pieces. To get any further I need to overload the assignment operator for the board class. The class is:

  19. Assignment Operators in Programming

    Assignment operators are used in programming to assign values to variables. We use an assignment operator to store and update data within a program. They enable programmers to store data in variables and manipulate that data. The most common assignment operator is the equals sign (=), which assigns the value on the right side of the operator to ...

  20. Assignment Operators In C++

    In C++, the addition assignment operator (+=) combines the addition operation with the variable assignment allowing you to increment the value of variable by a specified expression in a concise and efficient way. Syntax. variable += value; This above expression is equivalent to the expression: variable = variable + value; Example.

  21. Python Operators

    Assignment Operators in Python. Let's see an example of Assignment Operators in Python. Example: The code starts with 'a' and 'b' both having the value 10. It then performs a series of operations: addition, subtraction, multiplication, and a left shift operation on 'b'.