Kodeclik Logo

Our Programs

Courses

Learn More

Schedule

Kodeclik Blog

Understanding the Asterisk (*) Symbol in Programming Languages

The venerated asterisk symbol (“*”) is very popular in many programming languages and is used to denote a lot of concepts. Lets take a whirlwind tour!

What does asterisk mean in programming?

Asterisk in Python

In Python, the asterisk performs basic mathematical operations like multiplication between numbers and exponentiation when used as a double asterisk (x ** y).

# Basic multiplication and exponentiation
multiply = 9 * 7
expo = 4 ** 4
print(multiply)
print(expo)

This code demonstrates two fundamental mathematical operations using the asterisk. The first operation multiplies 9 and 7 using a single asterisk, while the second operation calculates 4 raised to the power of 4 using a double asterisk.

The output will be:

63
256

When working with functions, the asterisk enables powerful argument handling capabilities. Consider:

def collect_numbers(*values):
    total = sum(values)
    average = total / len(values)
    return total, average

result = collect_numbers(1, 2, 3, 4, 5)
print(f"Total: {result[0]}, Average: {result[1]}")

The function collect_numbers uses *values in its parameter definition, which means it can accept any number of positional arguments. When called, Python automatically packs all the provided arguments into a tuple named values. In this case, when we call collect_numbers(1, 2, 3, 4, 5), even though we are calling it with five arguments, the values parameter becomes a single tuple (1, 2, 3, 4, 5).

Inside the function, sum(values) adds up all numbers in the tuple (1 + 2 + 3 + 4 + 5 = 15), and len(values) counts the number of elements (5). The function then calculates the average by dividing the total by the count (15 / 5 = 3). Finally, it returns both values as a tuple using return total, average.

The result will be:

Total: 15, Average: 3.0

Note that this function is flexible - we could call it with any number of arguments, like collect_numbers(10, 20) or collect_numbers(1, 2, 3, 4, 5, 6, 7, 8), and it would still work correctly.

Here’s a second example:

def greet(title, first_name, last_name):
    return f"Hello, {title}. {first_name} {last_name}"

person_info = ["Dr", "Jane", "Smith"]
print(greet(*person_info))

# Multiple unpacking in a single call
names1 = ["Mr", "John"]
names2 = ["Doe"]
print(greet(*names1, *names2))

Note that the greet function expects three separate parameters (title, first_name, last_name), and the asterisk operator allows us to unpack a list into these individual arguments. When we write greet(*person_info), Python unpacks the list ["Dr", "Jane", "Smith"] into three separate arguments, effectively calling greet("Dr", "Jane", "Smith"), which outputs "Hello, Dr. Jane Smith".

The second part of the program shows how multiple lists can be unpacked in a single function call. The expression greet(*names1, *names2) unpacks both lists ["Mr", "John"] and ["Doe"] into individual arguments, combining them to match the function's parameters. This is equivalent to calling greet("Mr", "John", "Doe"), resulting in "Hello, Mr. John Doe".

The output will be:

Hello, Dr. Jane Smith
Hello, Mr. John Doe

Finally, consider:

def func(*, keyword_only):
    print(keyword_only)
    
func(keyword_only="value")

This code showcases how the bare asterisk in the function definition forces the parameter 'keyword_only' to be passed as a keyword argument only. Any attempt to call this function with a positional argument will result in an error.

The output will be:

value

Asterisk in C

In C, again, the asterisk can be used to perform mathematical operations. The multiplication operator, denoted by the asterisk symbol (*), is used to multiply two values. It is a binary arithmetic operator, which means that the multiplicand and the multiplier are its two operands.

int x = 10;
int y = 5;
int result = x * y;
printf("The multiplication of %d and %d is %d", x, y, result);

This code demonstrates multiplication in C using the asterisk operator. The program multiplies two integers x and y and stores the result in the result variable.

The output will be:

The multiplication of 10 and 5 is 50

In C, in addition, the asterisk importantly serves as the pointer operator. When declaring variables, an asterisk before the variable name creates a pointer that can store memory addresses. The asterisk is also used for dereferencing pointers to access the values stored at those memory addresses.

#include <stdio.h>

int main() {
    int x = 10;                     // Initialize x with 10
    printf("Before: x = %d\n", x);  // Print initial value
    
    int *ptr;                       // Declare pointer
    ptr = &x;                       // Point to x's address
    *ptr = 42;                      // Modify x through pointer
    
    printf("After: x = %d\n", x);   // Print modified value
    return 0;
}

This C program starts by creating an integer variable x initialized to 10 and prints this initial value. Then it declares a pointer variable ptr that can store the memory address of an integer. Using the address-of operator (&), it assigns the memory address of x to ptr, meaning ptr now "points to" x's location in memory.

After establishing this pointer relationship, the program uses the dereference operator (*) to modify the value stored at the memory location that ptr points to. By writing *ptr = 42, it changes the value at x's memory location to 42, which is then verified by printing x's new value. This demonstrates how pointers provide indirect access to variables through memory addresses, allowing us to modify variables without referencing them directly by name.

The output will be:

Before: x = 10
After: x = 42

The asterisk in C also plays a crucial role in function pointer declarations, enabling the creation of callbacks and indirect function calls, which are fundamental to many C programming patterns.

Here's a simple demonstration of function pointers and callbacks using asterisk notation in C:

#include <stdio.h>

void greet(char *name) {
    printf("Hello, %s!\n", name);
}

void farewell(char *name) {
    printf("Goodbye, %s!\n", name);
}

void process_name(void (*message_func)(char*), char *name) {
    message_func(name);
}

int main() {
    void (*func_ptr)(char*);
    
    func_ptr = &greet;
    process_name(func_ptr, "Alice");
    
    func_ptr = &farewell;
    process_name(func_ptr, "Bob");
    
    return 0;
}

This code demonstrates how function pointers enable callback mechanisms in C. The asterisk in void (*message_func)(char*) declares a function pointer that can point to any function taking a char pointer as an argument and returning void. The process_name function accepts this function pointer as a parameter, allowing it to call different functions dynamically. In the main function, we create a function pointer func_ptr and assign it to different functions (greet and farewell), demonstrating how the same processing function can execute different behaviors through callbacks.

The output will be:

Hello, Alice!
Goodbye, Bob!

Asterisk in C++

C++ inherits the pointer functionality from C but extends it with object-oriented features. The asterisk remains central to memory management and pointer operations, allowing developers to declare pointers to objects, manage dynamic memory allocation, and work with complex data structures. For instance, most of the above C programs will work (with minor modifications) with similar outputs.

In C++, the asterisk is also essential for implementing polymorphism through pointers to base classes and managing memory in sophisticated object hierarchies. It enables both low-level memory manipulation and high-level object-oriented programming paradigms.

#include <iostream>

class Animal {
public:
    virtual std::string speak() const {
        return "Generic animal sound";
    }
    virtual ~Animal() {}
};

class Dog : public Animal {
public:
    std::string speak() const override {
        return "Woof!";
    }
};

class Cat : public Animal {
public:
    std::string speak() const override {
        return "Meow!";
    }
};

int main() {
    Animal* animals[2];
    animals[0] = new Dog();
    animals[1] = new Cat();
    
    for(int i = 0; i < 2; i++) {
        std::cout << animals[i]->speak() << std::endl;
    }
    
    // Clean up memory
    for(int i = 0; i < 2; i++) {
        delete animals[i];
    }
    
    return 0;
}

This code demonstrates two key aspects of asterisk usage in C++ object-oriented programming. First, it shows polymorphism through base class pointers, where Animal* can point to any derived class object, allowing different derived classes to respond differently to the same function call. The asterisk in Animal* creates a pointer that enables this polymorphic behavior. Second, it shows memory management using new and delete operators, where the asterisk is used to declare pointers that manage dynamically allocated objects. When executed, this program outputs:

Woof!
Meow!

Asterisk in Javascript

In JavaScript, the asterisk (*) serves several distinct purposes. First it can be used to create generator functions:

function* generateNumbers() {
    yield 1;
    yield 2;
    yield 3;
}

const gen = generateNumbers();
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);

This generator function creates an iterator that pauses execution at each yield statement. When next() is called, the function executes until it hits a yield statement, returns that value, and pauses until next() is called again. This makes generators particularly useful for creating sequences or handling asynchronous operations.

The output will be:

1
2
3

The asterisk can also be used as an object method generator:

const obj = {
    *generator() {
        yield 'first';
        yield 'second';
    }
};

const gen = obj.generator();
console.log(gen.next().value);
console.log(gen.next().value);

When used in object methods, the asterisk syntax allows us to define generator methods directly within object literals. This example shows how generator functions can be integrated into object-oriented programming patterns, providing iterative capabilities to object methods. The result will be:

first
second

Asterisk in regular expressions

Finally, this is not specific to Javascript but is used in some form by libraries in many languages, including Python.

In regular expressions, the asterisk acts as a quantifier that matches zero or more occurrences of the preceding character. Consider:

const pattern = /js*/i;
const texts = ["j", "js", "jsss", "javascript"];
texts.forEach(text => {
    console.log(`"${text}" matches:`, text.match(pattern)[0]);
});

(The 'i' flag makes the match case-insensitive.) This example demonstrates how the asterisk helps create flexible pattern matching rules. For instance:

"j" matches: j
"js" matches: js
"jsss" matches: jsss
"javascript" matches: js

The last line might appear a bit confusing. Let us see how the regular expression /js*/i matches "javascript": The regular expression /js*/i breaks down as follows:

  • j matches the literal character "j"
  • s* matches zero or more occurrences of the letter "s"
  • The i flag makes the match case-insensitive, as mentioned earlier
  • When this pattern is applied to "javascript", it matches only "j" followed by "s" at the beginning of the word and stops there. It doesn't match the entire word because the pattern only looks for "j" followed by any number of "s" characters. Once it finds a character that isn't "s" (the "a" in this case), the matching stops.

    Summary

    In summary, the asterisk symbol (*) serves multiple fundamental purposes across programming languages, though its implementation varies significantly between them. In its most basic form, it acts as the multiplication operator in all languages - Python, C, C++, and JavaScript all use the single asterisk for multiplication operations. Python extends this mathematical usage by employing double asterisk (**) for exponentiation, a feature not present in the other languages.

    In Python, the asterisk plays a crucial role in function parameter handling, where it enables argument packing and unpacking. A single asterisk can collect multiple positional arguments into a tuple, while a double asterisk handles keyword arguments. JavaScript achieves similar functionality but uses the spread/rest operator (...) instead of the asterisk. C and C++ don't have direct parameter packing functionality with the asterisk.

    Each language thus has unique applications for the asterisk symbol. In Python, it's used for importing all names from a module and forcing keyword-only arguments in function definitions. JavaScript employs the asterisk to define generator functions and as a quantifier in regular expressions. C++ uses it for pointer-to-member operators in addition to its C-inherited pointer functionality.

    To conclude, the asterisk (*) is a versatile symbol in programming that serves different purposes depending on the programming language and context. From basic arithmetic operations to sophisticated memory management, the asterisk is fundamental to modern programming. The above diverse applications demonstrate how a single symbol has evolved to serve different purposes across programming paradigms while maintaining its fundamental role in basic arithmetic operations.

    Enjoy this blogpost? Want to learn Python or Javascript with us? Sign up for 1:1 or small group classes.

    Kodeclik sidebar newsletter

    Join our mailing list

    Subscribe to get updates about our classes, camps, coupons, and more.

    About

    Kodeclik is an online coding academy for kids and teens to learn real world programming. Kids are introduced to coding in a fun and exciting way and are challeged to higher levels with engaging, high quality content.

    Copyright @ Kodeclik 2025. All rights reserved.